/* 
 * File:   Surface.h
 * Author: johannes
 *
 * Created on December 28, 2013, 9:24 PM
 */

#ifndef SURFACE_H
#define	SURFACE_H

#include <string>
#include <vector>
#include <SDL2/SDL.h>

#include "Utility.h"

namespace GUL {
    namespace System {
        namespace Graphic {
            class Window;

            class Surface {
            private:

                SDL_Surface* m_Surface;
                const  Window& m_ReferenceWindow;

            protected:

                void ConvertPixels(int width, int height, Uint32 src_format, const void * src, int src_pitch, Uint32 dst_format, void * dst, int dst_pitch);
                void LowerBlit(SDL_Rect*, Surface&, SDL_Rect*);
                void LowerBlitScaled(SDL_Rect*, Surface&, SDL_Rect*);
                void UpperBlit(SDL_Rect*, Surface&, SDL_Rect*);
                void UpperBlitScaled(SDL_Rect*, Surface&, SDL_Rect*);

            public:

                Surface(Window&);
                Surface(Surface&);
                Surface(Window&, UPair boundary);
                Surface(Window&, SDL_Surface*);
                Surface(const Window&, std::string);
                virtual ~Surface();

                Surface& operator=(std::string&);
                Surface& operator=(SDL_Surface*);
                //        Surface& operator=(SDL_Rect*);

                operator SDL_Surface*() {
                    return this->m_Surface;
                }

                int Lock();
                void Unlock();

                int SetSurfaceRLE(int flag);

                int Colorkey();
                int Colorkey(int flag, Uint32 Key);

                int SurfaceColorMod(Uint8 r, Uint8 g, Uint8 b);
                std::vector<Uint8>& SurfaceColorMod(Uint8* r, Uint8* g, Uint8* b);
                int SurfaceAlphaMod(Uint8);
                Uint8 SurfaceAlphaMod();

                int SurfaceBlendMode(SDL_BlendMode blendMode);
                SDL_BlendMode SurfaceBlendMode();

                bool ClipRect(const SDL_Rect*);
                SDL_Rect* ClipRect();

                void FillRect(const SDL_Rect*, Uint32 color);
                void FillRects(const SDL_Rect*, int count, Uint32 color);

                void Blit();
                void BlitScaled();
                void Blit(SDL_Rect*, SDL_Rect*);
                void BlitScaled(SDL_Rect*, SDL_Rect*);
                
                void BlitTo(Surface&);
                void BlitScaledTo(Surface&);
                void BlitTo(SDL_Rect*,Surface&, SDL_Rect*);
                void BlitScaledTo(SDL_Rect*,Surface&, SDL_Rect*);

                void SoftStretch(SDL_Rect*, Surface&, SDL_Rect*);


                void Save(const std::string&);
                void Load(const std::string&);
                
                int wdith() { return this->m_Surface->w; }
                int height() {return this->m_Surface->h; }


            };
        }
    }

}
#endif	/* SURFACE_H */

